// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#ifndef _STDAFX_H_
#define _STDAFX_H_

#include <dlcom/cominc.h>
#include <dlcom/loadcom.hpp>

typedef _lComPtr<IBase> BasePtr;
typedef const _lComPtr<IBase>& BaseConstPtr;

typedef _lComPtr<IRot> RotPtr;
typedef const _lComPtr<IRot>& RotConstPtr;

typedef _lComPtr<ILibManager> LibManagerPtr;
typedef const _lComPtr<ILibManager> LibManagerConstPtr;

typedef _lComPtr<ICreator> CreatorPtr;
typedef const _lComPtr<ICreator> CreatorConstPtr;

typedef _lComPtr<IObjectRun> ObjectRunPtr;
typedef const _lComPtr<IObjectRun>& ObjectRunConstPtr;

typedef _lComPtr<IMainRun> MainRunPtr;
typedef const _lComPtr<IMainRun>& MainRunConstPtr;

typedef _lComPtr<IPlugin> PluginPtr;
typedef const _lComPtr<IPlugin> PluginConstPtr;

typedef _lComPtr<IPluginRun> PluginRunPtr;
typedef const _lComPtr<IPluginRun> PluginRunConstPtr;

typedef _lComPtr<IMsgPlugin> MsgPluginPtr;
typedef const _lComPtr<IMsgPlugin> MsgPluginConstPtr;

typedef _lComPtr<IMsg> MsgPtr;
typedef const _lComPtr<IMsg> MsgConstPtr;

typedef _lComPtr<IMsgProxy> MsgProxyPtr;
typedef const _lComPtr<IMsgProxy> MsgProxyConstPtr;

typedef _lComPtr<IClsFactory> ClsFactoryPtr;
typedef const _lComPtr<IClsFactory> ComClassFactoryConstPtr;

typedef _lComPtr<IExit> ExitPtr;
typedef const _lComPtr<IExit> ExitConstPtr;

template <class T> struct memless {
    bool operator()(const T& left, const T& right) const { return memcmp(&left, &right, sizeof(T)) < 0; }
};

template <class _Ty> class SortVector : public std::vector<_Ty>
{
public:
    typedef std::vector<_Ty> _base;
    void push_back(const _Ty& _Val)
    {
        if (_base::size() > 0) {
            push_back_sort(_Val);
        } else {
            _base::push_back(_Val);
        }
    }
    void push_back_sort(const _Ty& _Val)
    {
        typename _base::iterator _it = _base::begin();
        for (; _it != _base::end(); _it++) {
            if (_Val < *_it) {
                _base::insert(_it, _Val);
                return;
            }
        }

        if (_it == _base::end()) {
            _base::push_back(_Val);
        }
    }
};

class Com_Plugin
{
public:
    CLSID clsid;
    unsigned long loop;
    string strComponent;
    ~Com_Plugin()
    {
        loop = 0;
        strComponent.clear();
    }

    Com_Plugin(CLSID id, ULONG index, const char* component)
    {
        clsid = id;
        loop = index;
        strComponent = component;
    }

    CLSID GetClsid() const { return clsid; }

    unsigned long GetIndex() const { return loop; }

    string GetComponent() const { return strComponent; }

    bool operator>(const Com_Plugin& it) const { return GetIndex() > (it.GetIndex()); }

    bool operator<(const Com_Plugin& it) const { return !(operator>(it)); }
};

typedef SortVector<Com_Plugin> PluginVector;

typedef map<string, string> ComponentPlugin;
typedef map<string, string>::iterator ComponentPluginIterator;

class ClsInfo
{
public:
    string progid;
    string pname;
    ClsInfo()
    {
        progid.clear();
        pname.clear();
    }
    ~ClsInfo()
    {
        progid.clear();
        pname.clear();
    }
};

typedef memless<CLSID> clscmp;

typedef std::map<CLSID, ClsInfo, clscmp> ClsIdTable;
typedef ClsIdTable::iterator ClsIdTableiterator;
typedef ClsIdTable::const_iterator ClsIdTableConstiterator;
typedef std::pair<ClsIdTableiterator, bool> ClsIdTableBooliterator;

typedef std::map<string, CComLoader> ContainerTable;
typedef ContainerTable::iterator ContainerTableiterator;
typedef ContainerTable::const_iterator ContainerTableConstiterator;
typedef std::pair<ContainerTableiterator, bool> ContainerBooliterator;

#endif
